﻿package igz.fleaxy.ui.form.select
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	import igz.fleaxy.Fleaxy;
	import igz.fleaxy.ui.form.input.Input;
	import igz.fleaxy.ui.LinkUi;
	import igz.fleaxy.ui.scrollbar.ScrollBarV;
	import igz.fleaxy.ui.scrollbar.ScrollContainerUi;
	import igz.fleaxy.util.DataTableUtil;
	import igz.fleaxy.util.ObjectUtil;
	
	/**
	 * Select básico
	 * 
	 * @author Intelygenz | www.intelygenz.com
	 */
	public class SelectUi extends Sprite {
		
		protected var _Value : *;
		public function get $Value () : * {
			return _Value;
		}
		public function set $Value ( p_value:* ) : * {
			_Value = p_value;
			_Input.$Value = p_value;
		}
		
		protected var _Input : Input;
		public function get $Input():Input {
			return _Input;
		}
		
		protected var _ListItemsUi : Sprite;
		protected var _ListItemsContainer : ScrollContainerUi;
		public function get $ListItemsContainer() : ScrollContainerUi {
			return _ListItemsContainer;
		}
		
		protected var _ScrollV : ScrollBarV;
		
		protected var _SelectedOption : SelectItemUi;

		protected var _BtnSelect : LinkUi;

		protected var _Settings:Object = {
			 "inputSettings" : { "inputStyle" : {} }
			,"scrollContainerSettings" : { }
			,"scrollBarStyles" : { }
			,"scrollBarSettings" : { }
			,"selectItemSettings" : { }
			,"arrowColor": 0x000000
			,"listItemHeight":100
		};
		
		protected var _RelationsColNames:Object = { "COLUMN_LABEL" : "", "COLUMN_VALUE" : "" };
		
		protected var _Timer_ListItems_Hide:Timer;

		/**
		 * Crea un select básico, desplegable con elementos formados por texto únicamente
		 * 
		 * @param	p_name Nombre del select
		 * @param	p_settings { "inputSettings" : { "inputStyle" : {} }
								,"scrollContainerSettings" : { }
								,"scrollBarStyles" : { }
								,"scrollBarSettings" : { }
								,"selectItemSettings" : { }
								,"arrowColor": 0x000000
								,"listItemHeight":100
							}
		 * 
		 * @example
		 *
		 * _SearchSelectUi = new Select("search", { "inputSettings" : { "width" : 220
														 , "required" : true
														 , "example" : LocaleManager.$GetText("DIRECTORY", "SIMPLE_SEARCH_EXAMPLE")
														 , "inputStyle" : { "exampleStyle": "inputExample"
																		  , "inputTextStyle": "inputText"
																		  }
														 , "border" : 0x8b8b8b
													}
													,"scrollContainerSettings":{"width":220,"height":80,"backgroundAlpha":0.9,"border":0xcccccc}
													,"arrowColor":0x4d6185
													,"scrollBarStyles" : { "backgroundStyle" : "scrollBarBg", "markStyle" : "scrollBarMark" }
													,"selectItemSettings" : {"bgColor":0xc3e9ff,"bgBorder":0x64c5fe}
												}
									   );
		 */
		public function SelectUi ( p_name:String = "", p_settings:Object = null ) {
			ObjectUtil.$Merge( p_settings, _Settings );

			_Input = new Input( p_name, _Settings["inputSettings"] );
			addChild( _Input );

			_ListItemsUi = new Sprite();

			_ListItemsContainer = new ScrollContainerUi( _Settings["scrollContainerSettings"] );
			_ListItemsUi.addChild( _ListItemsContainer );

			_ScrollV = new ScrollBarV( _ListItemsContainer,  _Settings["scrollBarStyles"], _Settings["scrollBarSettings"] );
			_ListItemsUi.addChild( _ScrollV );

			_BtnSelect = new LinkUi(_CreateBtnSelectShape(), { "onMouseDown":_BtnSelect_OnMouseDown } );
			_BtnSelect.x = _Input.width;
			_BtnSelect.y = _Input.$TextUi.y;
			addChild( _BtnSelect );
			
			_Timer_ListItems_Hide = new Timer(500, 1);
			_Timer_ListItems_Hide.addEventListener(TimerEvent.TIMER_COMPLETE, _Timer_ListItems_Hide_OnTimer);

			addEventListener(MouseEvent.ROLL_OUT, _Start_ListItems_Hide);
			_ListItemsUi.addEventListener(MouseEvent.ROLL_OUT, _Start_ListItems_Hide);

			_ListItemsUi.addEventListener(MouseEvent.ROLL_OVER, _Stop_ListItems_Hide);

		}
		
		protected function _BtnSelect_OnMouseDown ( p_mouseEvent:MouseEvent ) : void {
			if ( _ListItemsUi.parent ) {
				_ListItems_Hide();
			}
			else {
				_ListItems_Show();
			}
		}
		
		public function $Draw () : void {
			
		}
		
		protected function _CreateBtnSelectShape () : Shape {
			var shape : Shape = new Shape();
			var size : Number = _Input.$TextUi.height;
			shape.graphics.beginFill( _Input.$Settings["background"] );
			shape.graphics.lineStyle( 1, _Input.$Settings["border"] );
			shape.graphics.drawRect( 0, 0, size, size );
			shape.graphics.endFill();
			
			var marginX : Number = size / 5;
			var marginY : Number = size / 3;
			shape.graphics.beginFill( _Settings["arrowColor"] );
			shape.graphics.lineStyle();
			shape.graphics.moveTo( marginX, marginY );
			shape.graphics.lineTo( size / 2, size-marginY );
			shape.graphics.lineTo( size-marginX, marginY );
			shape.graphics.lineTo( marginX, marginY );
			shape.graphics.endFill();
			
			return shape;
		}
		
		
		/**
		 * Genera a partir de un datatable todos los elementos que se mostraran en el Select.
		 * Elimina los que hubiera.
		 * TODO revisar
		 * @param	p_dataTable Datatable con todos los elementos a mostrar
		 * @param	p_relationColNames Nombre de las columnas a mostrar 
		 */
		public function $Load ( p_dataTable:Object, p_relationColNames:Object ) : void {
			$Clear();
			
			ObjectUtil.$Merge( p_relationColNames, _RelationsColNames );

			if ( DataTableUtil.$IsDataTable(p_dataTable) ) {
				var indexColumnName  : int = DataTableUtil.$ColumnIndex( p_dataTable, _RelationsColNames["COLUMN_LABEL"] );
				var indexColumnValue : int = DataTableUtil.$ColumnIndex( p_dataTable, _RelationsColNames["COLUMN_VALUE"] );
				
				if ( (indexColumnName != -1) && (indexColumnValue != -1) ) {
					var i : int;
					var itemLabel : String;
					var itemValue : String;
					for ( i = 0; i < DataTableUtil.$Length(p_dataTable); i++ ) {
						itemLabel = DataTableUtil.$ValueOf(p_dataTable, _RelationsColNames["COLUMN_LABEL"], i);
						itemValue = DataTableUtil.$ValueOf(p_dataTable, _RelationsColNames["COLUMN_VALUE"], i);

						$AddItem( itemLabel, itemValue );
					}
				}
				else {
					throw new Error("[igz.fleaxy.form.select.Select] $Load: La relación de columnas (p_relationColNames) no se ha especificado correctamente");
				}
			}
			else {
				throw new Error("[igz.fleaxy.form.select.Select] $Load: p_dataTable no es un DataTable válido");
			}
		}
		
		/**
		 * Añade un elemento con una determinada etiqueta y valor
		 * 
		 * @param	p_label etiqueta mostrada
		 * @param	p_value valor
		 * 
		 * 
		 * TODO seria posible añadir un elemento "SelectedItemAdvanceUi" con un p_label que pudiera ser de tipo, por ejemplo, sprite
		 */
		public function $AddItem ( p_label:*, p_value:* ) : SelectItemUi {
			
			var selectItemUi : SelectItemUi;
			selectItemUi = new SelectItemUi( this, _Settings["selectItemSettings"] );
			selectItemUi.$Load( p_label, p_value );
			selectItemUi.$Draw(_Input.width, _Input.$Settings["inputStyle"]["inputTextStyle"]);
			selectItemUi.y = _ListItemsContainer.$Container.height;
			_ListItemsContainer.addChild( selectItemUi );
			return selectItemUi;
		}
		
		/**
		 * Establece un elemento como seleccionado
		 * 
		 * @param	p_selectItem Elemento a mostrar como seleccionado
		 */
		public function $SelectItem( p_selectItem:SelectItemUi ) : void {
			if ( _SelectedOption != null ) {
				_SelectedOption.$Selected = false;
			}
			_SelectedOption = p_selectItem;
			_SelectedOption.$Selected = true;

			_ListItems_Hide();
			
			_Input.$TextUi.htmlText = p_selectItem.$Label;
			_Value = p_selectItem.$Value;
			
			dispatchEvent( new Event(Event.SELECT) );
		}
		
		private function _ListItems_Hide () : void {
			if ( _ListItemsUi.parent ) {
				Fleaxy.$Current.$Stage.removeChild( _ListItemsUi );
			}
			
			//Fleaxy.$Current.$Stage.removeEventListener(MouseEvent.MOUSE_DOWN, _Stage_OnMouseDown);
		}
		
		private function _ListItems_Show () : void {
			Fleaxy.$Current.$Stage.addChild( _ListItemsUi );
			
			var newPos : Point = localToGlobal( new Point( _Input.x, _Input.y+_Input.height ) );
			_ListItemsUi.y = newPos.y+1;
			_ListItemsUi.x = newPos.x;
			
			//Fleaxy.$Current.$Stage.addEventListener(MouseEvent.MOUSE_DOWN, _Stage_OnMouseDown);
			
			var listHeight : Number = _ListItemsContainer.$Container.height;
			if ( listHeight < _Settings["listItemHeight"] ) {
				_ListItemsContainer.height = listHeight;
			}
			else {
				_ListItemsContainer.height = _Settings["listItemHeight"];
			}
		}
		
		private function _Stage_OnMouseDown ( p_mouseEvent:MouseEvent ) : void {
			//_ListItems_Hide();
		}
		
		public function $Enable () : void {
			_BtnSelect.$Enable();
			_Input.$Enable();
		}
		
		public function $Disable () : void {
			_BtnSelect.$Disable();
			_Input.$Disable();
		}
		
		public function $Clear () : void {
			_ListItemsContainer.$Clear();
		}

		public function _Start_ListItems_Hide ( p_mouseEvent:MouseEvent ):void {
			_Timer_ListItems_Hide.reset();
			_Timer_ListItems_Hide.start();
		}
		public function _Stop_ListItems_Hide ( p_mouseEvent:MouseEvent ):void {
			_Timer_ListItems_Hide.stop();
		}
		public function _Timer_ListItems_Hide_OnTimer ( p_timerEvent:TimerEvent ):void {
			_ListItems_Hide();
		}

		override public function get height():Number {
			return _Input.height;
		}
		
		override public function get width():Number {
			return _Input.width + _BtnSelect.width;
		}
	}
	
}